package com.firefly.admin.system.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.firefly.admin.common.constant.Constants;
import com.firefly.admin.common.enums.ResultCodeEnum;
import com.firefly.admin.common.utils.TreeUtil;
import com.firefly.admin.common.vo.Result;
import com.firefly.admin.system.service.FySystemOrganizationService;
import com.firefly.admin.system.service.FySystemUserService;
import com.firefly.admin.system.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import com.firefly.admin.system.entity.FySystemOrganization;
import com.firefly.admin.system.entity.FySystemUser;
import com.firefly.admin.system.mapper.FySystemOrganizationMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class FySystemOrganizationServiceImpl implements FySystemOrganizationService {

    @Autowired
    private FySystemOrganizationMapper fySystemOrganizationMapper;
    @Lazy
    @Autowired
    private FySystemUserService fySystemUserService;

    /**
     * 查询系统组织机构列表接口
     *
     * @param systemOrgQueryVo 查询参数
     * @return 列表
     */
    @Override
    public Result<List<FySystemOrganization>> getSystemOrgList(SystemOrgQueryVo systemOrgQueryVo) {
        log.info("###########FySystemOrganizationServiceImpl getSystemOrgList param = {}", JSONObject.toJSONString(systemOrgQueryVo));
        LambdaQueryWrapper<FySystemOrganization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(systemOrgQueryVo.getOrgName()), FySystemOrganization::getOrgName, systemOrgQueryVo.getOrgName());
        queryWrapper.eq(StringUtils.isNotBlank(systemOrgQueryVo.getOrgStatus()), FySystemOrganization::getOrgStatus, systemOrgQueryVo.getOrgStatus());
        queryWrapper.eq(FySystemOrganization::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        queryWrapper.orderByDesc(FySystemOrganization::getOrgId);
        List<FySystemOrganization> organizationList = fySystemOrganizationMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(organizationList)) {
            return Result.success();
        }
        List<FySystemOrganization> allOrgList = fySystemOrganizationMapper.selectList(null);
        Map<Long, FySystemOrganization> allOrgMap = allOrgList.stream().collect(Collectors.toMap(FySystemOrganization::getOrgId, org -> org));
        for (FySystemOrganization fySystemOrganization : organizationList) {
            FySystemUser systemUser = fySystemUserService.findUserById(fySystemOrganization.getDirectorId());
            fySystemOrganization.setDirector(systemUser);
            recursionParentOrg(allOrgMap, organizationList, fySystemOrganization);
        }
        List<FySystemOrganization> orgList = TreeUtil.makeOrgList(organizationList, Constants.ORG_TOP_NODE);
        return Result.success(orgList);
    }

    private void recursionParentOrg(Map<Long, FySystemOrganization> allOrgMap, List<FySystemOrganization> resultOrgList, FySystemOrganization fySystemOrganization) {
        FySystemOrganization systemOrganization = allOrgMap.get(fySystemOrganization.getParentId());
        fySystemOrganization.setParent(systemOrganization);
        if (fySystemOrganization.getParentId().longValue() == Constants.ORG_TOP_NODE) {
            return;
        }
        if (systemOrganization != null) {
            List<Long> collect = resultOrgList.stream().map(FySystemOrganization::getOrgId).collect(Collectors.toList());
            if (!collect.contains(systemOrganization.getOrgId())) {
                resultOrgList.add(systemOrganization);
                recursionParentOrg(allOrgMap, resultOrgList, systemOrganization);
            }
        }
    }

    /**
     * 系统组织机构信息新增接口
     *
     * @param fySystemOrganization 组织机构信息
     * @return 操作结果
     */
    @Override
    public Result<FySystemOrganization> add(FySystemOrganization fySystemOrganization) {
        if (fySystemOrganization == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        ResultCodeEnum resultCodeEnum = checkOrgParam(fySystemOrganization);
        if (resultCodeEnum != null) {
            return Result.getResult(resultCodeEnum);
        }
        int rows = fySystemOrganizationMapper.insert(fySystemOrganization);
        if (rows <= 0) {
            return Result.getResult(ResultCodeEnum.ADD_EXCEPTION);
        }
        return Result.success(fySystemOrganization);
    }

    /**
     * 系统组织机构信息编辑接口
     *
     * @param fySystemOrganization 组织机构信息
     * @return 操作结果
     */
    @Override
    public Result<FySystemOrganization> update(FySystemOrganization fySystemOrganization) {
        if (fySystemOrganization == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        Long orgId = fySystemOrganization.getOrgId();
        if (orgId == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        FySystemOrganization systemOrganization = fySystemOrganizationMapper.selectById(orgId);
        if (systemOrganization == null) {
            return Result.getResult(ResultCodeEnum.SYSTEM_ORG_NOT_FOUND);
        }
        ResultCodeEnum resultCodeEnum = checkOrgParam(fySystemOrganization);
        if (resultCodeEnum != null) {
            return Result.getResult(resultCodeEnum);
        }
        int rows = fySystemOrganizationMapper.updateById(fySystemOrganization);
        if (rows <= 0) {
            return Result.getResult(ResultCodeEnum.UPDATE_EXCEPTION);
        }
        return Result.success(fySystemOrganization);
    }

    private ResultCodeEnum checkOrgParam(FySystemOrganization fySystemOrganization) {
        Long parentId = fySystemOrganization.getParentId();
        if (parentId == null) {
            return ResultCodeEnum.SYSTEM_ORG_PARENT_NOT_NULL;
        }
        FySystemOrganization parentOrg = fySystemOrganizationMapper.selectById(parentId);
        if (parentOrg == null) {
            return ResultCodeEnum.SYSTEM_ORG_PARENT_NOT_NULL;
        }
        Long orgId = fySystemOrganization.getOrgId();
        String orgName = fySystemOrganization.getOrgName();
        if (StringUtils.isBlank(orgName)) {
            return ResultCodeEnum.SYSTEM_ORG_NAME_NOT_NULL;
        }
        LambdaQueryWrapper<FySystemOrganization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemOrganization::getOrgName, orgName);
        queryWrapper.eq(FySystemOrganization::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        List<FySystemOrganization> systemOrganizationList = fySystemOrganizationMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(systemOrganizationList)) {
            if (orgId == null) {
                //新增
                return ResultCodeEnum.SYSTEM_ORG_NAME_EXIST;
            }
            //编辑
            boolean isExist = systemOrganizationList.stream().allMatch(systemOrganization -> systemOrganization.getOrgId().longValue() != orgId.longValue());
            if (isExist) {
                return ResultCodeEnum.SYSTEM_ORG_NAME_EXIST;
            }
        }
        if (orgId == null && StringUtils.isBlank(fySystemOrganization.getOrgStatus())) {
            fySystemOrganization.setOrgStatus(Constants.Status.ENABLE);
        }
        return null;
    }

    /**
     * 系统组织机构状态编辑接口
     *
     * @param systemOrgStatusUpdateVo 状态信息
     * @return 操作结果
     */
    @Override
    public Result<FySystemOrganization> updateStatus(SystemOrgStatusUpdateVo systemOrgStatusUpdateVo) {
        if (systemOrgStatusUpdateVo == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        Long orgId = systemOrgStatusUpdateVo.getOrgId();
        if (orgId == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        FySystemOrganization fySystemOrganization = fySystemOrganizationMapper.selectById(orgId);
        if (fySystemOrganization == null) {
            return Result.getResult(ResultCodeEnum.SYSTEM_ORG_NOT_FOUND);
        }
        String orgStatus = systemOrgStatusUpdateVo.getOrgStatus();
        if (StringUtils.isBlank(orgStatus)) {
            return Result.getResult(ResultCodeEnum.SYSTEM_ORG_STATUS_NOT_NULL);
        }
        fySystemOrganization.setOrgStatus(orgStatus);
        int rows = fySystemOrganizationMapper.updateById(fySystemOrganization);
        if (rows <= 0) {
            return Result.getResult(ResultCodeEnum.UPDATE_EXCEPTION);
        }
        return Result.success(fySystemOrganization);
    }

    /**
     * 系统组织机构信息删除接口
     *
     * @param orgId 组织机构ID
     * @return 操作结果
     */
    @Override
    public Result<String> delete(Long orgId) {
        if (orgId == null) {
            return Result.getResult(ResultCodeEnum.REQUEST_PARAM_EXCEPTION);
        }
        FySystemOrganization fySystemOrganization = fySystemOrganizationMapper.selectById(orgId);
        if (fySystemOrganization == null) {
            return Result.getResult(ResultCodeEnum.SYSTEM_ORG_NOT_FOUND);
        }
        List<FySystemUser> systemUserList = fySystemUserService.findUserByOrgId(orgId);
        if (!CollectionUtils.isEmpty(systemUserList)) {
            return Result.getResult(ResultCodeEnum.SYSTEM_ORG_BIND_USER_NOT_ALLOW_DELETE);
        }
        fySystemOrganization.setDeleteFlag(Constants.DeleteFlag.DELETE);
        int rows = fySystemOrganizationMapper.updateById(fySystemOrganization);
        if (rows <= 0) {
            return Result.getResult(ResultCodeEnum.DELETE_EXCEPTION);
        }
        return Result.success();
    }

    /**
     * 通过组织机构ID获取组织机构信息
     *
     * @param orgId 组织机构ID
     * @return 组织机构信息
     */
    @Override
    public FySystemOrganization findById(Long orgId) {
        return fySystemOrganizationMapper.selectById(orgId);
    }

    /**
     * 通过组织机构ID获取所有子组织ID
     *
     * @param orgId 组织机构ID
     * @return 自组织机构ID列表
     */
    @Override
    public List<Long> findChildrenOrgList(Long orgId) {
        List<Long> childrenOrgIds = new ArrayList<>();
        LambdaQueryWrapper<FySystemOrganization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemOrganization::getParentId, orgId);
        queryWrapper.eq(FySystemOrganization::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        List<FySystemOrganization> childrenOrgList = fySystemOrganizationMapper.selectList(queryWrapper);
        if (childrenOrgList.isEmpty()) {
            childrenOrgIds.add(orgId);
        } else {
            for (FySystemOrganization fySystemOrganization : childrenOrgList) {
                childrenOrgIds.add(fySystemOrganization.getOrgId());
                childrenOrgIds.addAll(findChildrenOrgList(fySystemOrganization.getOrgId()));
            }
        }
        return childrenOrgIds;
    }

    /**
     * 获取组织机构树列表接口
     *
     * @return 组织机构树列表
     */
    @Override
    public Result<List<OrgTree>> getOrgTree() {
        LambdaQueryWrapper<FySystemOrganization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemOrganization::getOrgStatus, Constants.Status.ENABLE);
        queryWrapper.eq(FySystemOrganization::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        List<FySystemOrganization> systemOrganizationList = fySystemOrganizationMapper.selectList(queryWrapper);
        List<OrgTree> orgTreeList = new ArrayList<>();
        FySystemOrganization fySystemOrganization = fySystemOrganizationMapper.selectById(Constants.ORG_TOP_NODE);
        OrgTree orgTree = new OrgTree();
        orgTree.setOrgId(fySystemOrganization.getOrgId());
        orgTree.setLabel(fySystemOrganization.getOrgName());
        List<OrgTree> children = TreeUtil.makeOrgTree(systemOrganizationList, Constants.ORG_TOP_NODE);
        orgTree.setChildren(children);
        orgTreeList.add(orgTree);
        return Result.success(orgTreeList);
    }

    /**
     * 通过父节点ID获取能作选负责人的账号信息
     *
     * @param parentId 父节点ID
     * @return 可选负责人账号列表
     */
    @Override
    public Result<List<GroupSelect>> getDirectorList(Long parentId) {
        FySystemOrganization fySystemOrganization = fySystemOrganizationMapper.selectById(parentId);
        if (fySystemOrganization == null) {
            return Result.getResult(ResultCodeEnum.SYSTEM_ORG_PARENT_NOT_NULL);
        }
        LambdaQueryWrapper<FySystemOrganization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemOrganization::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        List<FySystemOrganization> allOrgList = fySystemOrganizationMapper.selectList(queryWrapper);
        Map<Long, FySystemOrganization> allOrgMap = allOrgList.stream().collect(Collectors.toMap(FySystemOrganization::getOrgId, org -> org));
        Set<Long> parentIdsList = new HashSet<>();
        recursionParentId(allOrgMap, parentIdsList, parentId);
        List<FySystemUser> fySystemUsers = fySystemUserService.findUserByOrgIds(parentIdsList);
        List<GroupSelect> groupSelectList = new ArrayList<>();
        if (CollectionUtils.isEmpty(fySystemUsers)) {
            return Result.success(groupSelectList);
        }
        Map<Long, List<FySystemUser>> systemUserMap = fySystemUsers.stream().collect(Collectors.groupingBy(FySystemUser::getOrgId));
        for (Long orgId : systemUserMap.keySet()) {
            FySystemOrganization systemOrganization = allOrgMap.get(orgId);
            GroupSelect groupSelect = new GroupSelect();
            groupSelect.setLabel("[组织机构] " + systemOrganization.getOrgName());
            List<FySystemUser> systemUserList = systemUserMap.get(orgId);
            if (CollectionUtils.isEmpty(systemUserList)) {
                continue;
            }
            List<SelectOption> selectOptionList = new ArrayList<>();
            for (FySystemUser fySystemUser : systemUserList) {
                SelectOption selectOption = new SelectOption();
                selectOption.setLabel(fySystemUser.getRealName() + " (" + fySystemUser.getUserName() + ")");
                selectOption.setValue(fySystemUser.getUserId());
                selectOptionList.add(selectOption);
            }
            groupSelect.setOptions(selectOptionList);
            groupSelectList.add(groupSelect);
        }
        return Result.success(groupSelectList);
    }

    /**
     * 查询所有正常状态组织机构
     *
     * @return 组织机构列表
     */
    @Override
    public List<FySystemOrganization> getAllUsableOrg() {
        LambdaQueryWrapper<FySystemOrganization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FySystemOrganization::getDeleteFlag, Constants.DeleteFlag.NORMAL);
        queryWrapper.eq(FySystemOrganization::getOrgStatus, Constants.Status.ENABLE);
        return fySystemOrganizationMapper.selectList(queryWrapper);
    }

    private void recursionParentId(Map<Long, FySystemOrganization> allOrgMap, Set<Long> parentIdsList, Long orgId) {
        parentIdsList.add(orgId);
        if (orgId.longValue() == Constants.ORG_TOP_NODE) {
            return;
        }
        FySystemOrganization fySystemOrganization = allOrgMap.get(orgId);
        if (fySystemOrganization != null) {
            recursionParentId(allOrgMap, parentIdsList, fySystemOrganization.getParentId());
        }
    }
}
